<?php

namespace App\Backend\Middleware;

use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\Admin;
use App\Models\AdminLog;
use App\Models\Role;
use App\Models\Auth as  AuthModel;
use App\Libs\TokenLibrary;

/**
 * 验证token，并且过期自动刷新
 * Class AuthJwtToken
 * @package App\Http\Middleware
 */
class AuthJwtToken extends BaseMiddleware
{
    private $no_need_permission = [
        'backend/login','backend/logout','backend/forgotPassword','backend/captcha','backend/sms','backend/captchValidate','backend/forgotPassword','backend/logout',
        'backend/profile/detail','backend/upload','backend/profile/editInfo','backend/profile/updateMobile','backend/profile/updatePassword'
    ];

    /**
     * @param $request
     * @param Closure $next
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|mixed
     * @throws JWTException
     */
    public function handle($request, Closure $next)
    {   
        $authToken = $request->header('Authorization');
        if(!$authToken){
            return response(['code'=>401,'message'=>'请登录']);
        }
        //die("sdfsd");
        try{
            $authToken = trim(ltrim($authToken,'bearer'));
            $res = TokenLibrary::validateToken($authToken);

            $data = (array)$res;
            $userinfo = (array)$data['data'];
            $token = cache()->get("token_backend_".$userinfo['user_id'].'_'.$data['iat']);
            if(!$token || $authToken != $token){
                return response(['code'=>401,'message'=>'请重新登录']);
            }
            $admin_user = Admin::where('id','=',$userinfo['user_id'])->first();
            $path = $request->path();
            if($admin_user['role_id'] != 1 && !$this->checkRight($admin_user['role_id'], $path)){
                return response(['code'=>301,'message'=>'没有权限']);
            }  
            //记录操作日志
            AdminLog::insert([
                'admin_id'   => $admin_user['id'],
                'admin_name' => $admin_user['username'],
                'path'       => $request->path(),
                'ip'         => $request->ip(),
                'user_agent' => substr($request->server('HTTP_USER_AGENT'), 0, 255),
                'create_time'=> time()
            ]); 
            $request->admin_user = $admin_user->only(['id', 'username', 'nickname','mobile']);
            $request->admin_user['iat'] = $data['iat'];
        }catch (\Exception $e){
            return response(['code'=>401,'message'=>'请重新登录']);
        }
        return $next($request);
    }

    /**
     * @param $request
     * @param Closure $next
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|mixed
     * @throws JWTException
     */
    public function handle_bak($request, Closure $next, $role = 'backend')
    {   
        // 检查此次请求中是否带有 token，如果没有则抛出异常。
        $authToken = Auth::guard($role)->getToken();
        if(!$authToken){
            return response(['code'=>401,'message'=>'请登录']);
        }
        // 检测用户的登录状态，如果正常则通过
        if (Auth::guard($role)->check()) {
            //$admin_id = Auth::guard($role)->payload()['sub'];
            $admin_user = Auth::guard($role)->user();
            $path = $request->path();
            if($admin_user['role_id'] != 1 && !$this->checkRight($admin_user['role_id'], $path)){
                return response(['code'=>301,'message'=>'没有权限']);
            }  
            //记录操作日志
            AdminLog::insert([
                'admin_id'   => $admin_user['id'],
                'admin_name' => $admin_user['username'],
                'path'       => $request->path(),
                'ip'         => $request->ip(),
                'user_agent' => substr($request->server('HTTP_USER_AGENT'), 0, 255),
                'create_time'=> time()
            ]); 
            $time = Auth::guard($role)->payload()['exp'];
            //刷新Token
            if(($time - time()) < 10*60 && ($time - time()) > 0){
                $token = Auth::guard($role)->refresh();
                if($token){
                    $request->headers->set('Authorization', 'Bearer '.$token);
                }else{
					return response(['code'=>401,'message'=>'请重新登录']);
                }

                // 在响应头中返回新的 token
                $respone = $next($request);
                if(isset($token) && $token){
                    $respone->headers->set('Authorization', 'Bearer '.$token);
                }
                return $respone;
            }
            $request->admin_user = $admin_user->only(['id', 'username', 'nickname','mobile']);
            //token通过验证 执行下一补操作
            return $next($request);
        }
		return response(['code'=>401,'message'=>'请重新登录']);
    }
  

    /**
     * 验证权限
     */
    private function checkRight($role_id, $path)
    {
        if(empty($role_id) || empty($path)) return false;
        if($role_id == 1 || in_array($path, $this->no_need_permission)) return true;
        $role = Role::getInfo($role_id);
        if(empty($role)) return false;
        $where = [
            ['status','<>',-1],
            [function($query) use ($role){
                $query->whereIn('id', explode(',',$role->auth));
            }]
        ];
        $routes = array_filter(array_column(AuthModel::where($where)->select('route')->get()->toArray(),'route'));
        if(in_array($path,$routes)) {
            return true;
        }else{
            return false;
        }

    }

}
